package com.zj.sms;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.zj.sms.bean.UrlRecordVo;
import com.zj.sms.constant.CommonUtil;
import com.zj.sms.constant.Constants;
import com.zj.sms.constant.Seed;

/**
 * 解析页面内容工具
 * 将符合条件的url添加到Seed.unVisitedQueue队列中
 * @author zj20160705
 * 1.经过测试，全网页覆盖扫描的话，有很多无用的网页会被扫描到，比如一些新闻相关的网页，和本目的根本不相关
 * 	可以考虑去掉。具体实现可以尝试如果在一个网址url的网页上没找到想要的数据，
 * 	截取该url 第fixNum(fixNum=3|4)个/之前的段，然后算出其hashcode,存在一个map里面并记数。
 * 	当同一个连接下的多个分支都没有找到想要的数据是，因为hashcode相同，则将map里的记数加1，当计数达到n时
 * 	则将该url的截取段加入需要过滤的队列filterList中。
 * 2.所有扫描的url中如果包含或者以fileterList中的数据开始的话，则认为该url不包含实际价值，直接丢弃。当然
 * 	也可以将该url写入filtered.txt中，后面再一个个url去找页面上是否有相关数据来验证本设计
 */
public class ReleaseContentUtil {
	private static Logger logger = Logger.getLogger(ReleaseContentUtil.class);
	/**
	 * @param content 网页内容
	 * @param index 该网页的深度
	 */
	public static void releaseContent(UrlRecordVo uv,String content){
		long startTime = System.currentTimeMillis();
		//第一步:找网页上是否存在手机号 并且 验证码的字符串
		String compile = ".*手机号|.*验证码";
		Pattern pattern = Pattern.compile(compile);//匹配多行，java默认匹配一行
		Matcher matcher = pattern.matcher(content);
		if(matcher.find()){//必须同时存在手机号和验证码
			logger.info(uv.getUrl() +"\t找到一个: "+matcher.group(0));
			FileUtil.createFile(Constants.path, "ok.txt", uv.toString());
			if(matcher.groupCount()>1){
				FileUtil.createFile(Constants.path, "ok2.txt", uv.toString());
			}
		}else{//如果未在网页内找到特征字符，则对该网页url做过滤处理
			String key = getPreStr(uv.getUrl());//url前n个字符串
			if(key != null){
				if(!Constants.filterList.contains(key)){//如果key不包含在Constants.filterList中
					if(Constants.countMap.containsKey(key)){//如果key已经存在countMap里，则将值加1
						int n = Constants.countMap.get(key);//已经被计数多少次
						if(n<Constants.filterN){//如果计数次数还未达到设置值，则继续计数
							Constants.countMap.put(key, n+1);//将该计数加1
						}else{//已经达到设置值后，将该key加入过滤列表filterList，并将key从countMap中移除
							Constants.filterList.add(key);
							Constants.countMap.remove(key);
						}
					}else{//key不存在countMap则将其计数置为1
						Constants.countMap.put(key,1);
					}
				}
			}
		}
		//已达到限制的最深目录
		if(uv.getIndex()>=Constants.index){
			logger.info(uv.getUrl()+"已达到最深层，停止向下寻找");
			return;
		}
		
		compile = "<a.*?href=(.*?)(?=\\s|\\>).*?>(.*?)</a>";
		pattern = Pattern.compile(compile,Pattern.MULTILINE | Pattern.DOTALL);//匹配多行，java默认匹配一行
		matcher = pattern.matcher(content);
		int count = 0;
		while(matcher.find()){
			++count;
			String url = matcher.group(1).replaceAll("\"", "");
			UrlRecordVo temp = new UrlRecordVo(uv.getIndex()+1,matcher.group(2),uv.getPath(),url);
			if(!Seed.unVisitedQueue.contains(temp) && !Seed.visitedQueue.contains(url) && url.toLowerCase().startsWith("http")){
				logger.info(Seed.unVisitedQueue.size()+" unVisitedQueue add : "+temp);
				Seed.unVisitedQueue.add(temp);
			}
		}
		logger.info("匹配的次数:"+count+",耗时秒:"+(System.currentTimeMillis()-startTime)/1000);
	}
	/**
	 * @param content 网页内容
	 * @param index 该网页的深度
	 */
	public static void releaseContent(int index,String baseUrl,String content){
		//第一步:找网页上是否存在手机号 并且 验证码的字符串
		String compile = ".*手机|.*验证码";
		Pattern pattern = Pattern.compile(compile);//匹配多行，java默认匹配一行
		Matcher matcher = pattern.matcher(content);
		if(matcher.find()){//必须同时存在手机号和验证码
			logger.info(matcher.group(0));
			FileUtil.createFile(Constants.path, "ok.txt", Thread.currentThread().getName()+"\t"+baseUrl);
			if(matcher.groupCount()>1)
			FileUtil.createFile(Constants.path, "ok2.txt", Thread.currentThread().getName()+"\t"+baseUrl);
		}
		if(index>=Constants.index){
			logger.info(baseUrl+"已达到最深层，停止向下寻找");
			return;//已达到限制的最深目录
		}
		compile = "<a.*?href=(.*?)(?=\\s|\\>).*?>(.*?)</a>";
		pattern = Pattern.compile(compile,Pattern.MULTILINE | Pattern.DOTALL);//匹配多行，java默认匹配一行
		matcher = pattern.matcher(content);
		int count = 0;
		while(matcher.find()){
			System.out.println("匹配的次数:"+(++count));
			String url = matcher.group(1).replaceAll("\"", "");
			if(!Seed.visitedQueue.contains(url)){
				System.out.println(Seed.unVisitedQueue.size()+"未访问队列添加: "+url);
				Seed.unVisitedQueue.add(new UrlRecordVo(index+1,matcher.group(2),baseUrl+"-->"+url,url));
			}
		}
	}
	public static void releaseContentBak(String content){
		//String compile = "<a.*?href=\"(.*?)?=\">(.*?)</a>";
		//String compile = "<a.*?href=(.*?)(?=\\s).*?>(.*?)</a>";//基本 ok
		/*解读:取a标签内的href与a主题. 第一个.*?表示匹配从<a到href间的任意字符,但是不计入所想找的字符内
		    第二个(.*?)(?=\\s|\\>) 表示从href=之后开始找到第一个\\s即空格或者第一个\\>即>的字符为止，计入所要找的第一个字符串内，它的格式是(.*?)
		    第三个.*?>表示一直到>为止，必须要
		   第四个(.*>)表示a标签内的数据数据
		 */
		String compile = "<a.*?href=(.*?)(?=\\s|\\>).*?>(.*?)</a>";
		Pattern pattern = Pattern.compile(compile,Pattern.MULTILINE | Pattern.DOTALL);//匹配多行，java默认匹配一行
		Matcher matcher = pattern.matcher(content);
		int count = 0;
		while(matcher.find()){
			System.out.println("匹配的次数:"+(++count));
			for(int i=0;i<=matcher.groupCount();i++){
				System.out.println(matcher.group(i));
			}
		}
		System.out.println("end!");
	}
	public static String getPreStr(String str){
		return CommonUtil.getPreUrl(str, Constants.tag, Constants.fixNum);
	}
}
